﻿package 
{
	import adobe.utils.CustomActions;
	import flash.display.MorphShape;
	import flash.display.MovieClip;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.display.Graphics;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	/**
	 * ...
	 * @author Miles Aurbeck
	 */
	
	 [SWF(width = "600", height = "600", frameRate = "24", backgroundColor = "0xC0C0C0")]
	 
	public class Main extends Sprite 
	{
		public var player:Array = new Array();
		public var obj:Array = new Array();
		
		public var colors:Array = new Array(0x800000, 0x0000FF, 0x008000);
		
		public var vertA:Array = new Array();
		public var vertB:Array = new Array();
		public var vertC:Array = new Array();
		public var source:Array = new Array();
		public var turn_source:Array = new Array();
		public var bound:Array = new Array();
		public var boundEst:Array = new Array();
		
		public var screenMC:Sprite = new Sprite();
		public var walls_A:Sprite = new Sprite();
		public var references_A:Sprite = new Sprite();
		public var walls_B:Sprite = new Sprite();
		public var references_B:Sprite = new Sprite();
		public var walls_C:Sprite = new Sprite();
		public var references_C:Sprite = new Sprite();
		
		public var objMC:Sprite = new Sprite();
		
		public var intervalA:Number = 0;
		public var slopeA:Number = 0;		
		public var wallLengthA:Number = 0;

		public var intervalB:Number = 0;
		public var slopeB:Number = 0;		
		public var wallLengthB:Number = 0;
		
		public var intervalC:Number = 0;
		public var slopeC:Number = 0;		
		public var wallLengthC:Number = 0;
		
		public var prevDir:Boolean = true;

		public var alphaEnum:Array = new Array();
		public var positionEnum:Array = new Array();
		
		public function Main():void 
		{
			populateAlphas();
			populatePositions();
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function populateAlphas():void {
			alphaEnum.push(9);
			alphaEnum.push("A");
			alphaEnum.push("B");
			alphaEnum.push("C");
		}
		
		private function populatePositions():void {
			for (var i:Number = 0; i <= 10; i++) {
				positionEnum.push(i);
			}
			for (var j:Number = 0.0; j <= 11; j++) {
				positionEnum.push(j+11);
			}

		}
		
		public function init(e:Event = null):void 
		{
			trace("init");
			
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			stage.addEventListener(KeyboardEvent.KEY_DOWN, key);
			stage.addEventListener(MouseEvent.CLICK, click);
			
			initPlr();
			makeObjs();
			setupScreen();			
			
			addChild(screenMC);
			screenMC.addChild(walls_A);
			screenMC.addChild(references_A);
			screenMC.addChild(walls_B);
			screenMC.addChild(references_B);
			screenMC.addChild(walls_C);
			screenMC.addChild(references_C);
			screenMC.addChild(objMC);
		}
		
		private function initPlr():void {
			player["position"] = 0.0;
			player["Rposition"] = 0.0;
			player["sightLen"] = 20;
			player["speed"] = 10;
		}
		
		public function makeObjs():void {
			for (var i:int = 0; i < 3; i++) {
				
				var objs:MovieClip = new MovieClip();
				obj.push(objs);
				
				obj[i].graphics.lineStyle(3);
				obj[i].graphics.beginFill(colors[i]);
				obj[i].graphics.drawCircle(0, 0, 5);
				
				objMC.addChild(obj[i]);
				obj[i].graphics.endFill();
				
				obj[i].x = 250+(30*(i+1));
				obj[i].y = 250+(30*((i%2)+1));
				
				obj[i]["position"] = 20 * (i + 1);	
				obj[i].name = "obj" + i;
				obj[i].visible = false;
			}
		}
		
		public function update():void {
			drawReferencePts();
		}		
		
		public function setupScreen():void {
			bound[2] = new Point(0,0);
			bound[3] = new Point(0, stage.stageHeight);
			bound[1] = new Point(stage.stageWidth, 0);
			bound[4] = new Point(stage.stageWidth, stage.stageHeight);
			
			//trace("before");
			//trace("src: " + source[2].x + "," + source[2].y);
			//trace("bnd: " + source[2].x + "," + source[2].y);

			source[2] = new Point((stage.stageWidth / 4), (stage.stageHeight / 4));
			source[3] = new Point((stage.stageWidth / 4), (stage.stageHeight / 4) * 3);
			source[1] = new Point((stage.stageWidth / 4) * 3, (stage.stageHeight / 4));
			source[4] = new Point((stage.stageWidth / 4) * 3, (stage.stageHeight / 4) * 3);
			
			vertA[2] = new Point((stage.stageWidth / 4), (stage.stageHeight / 4));
			vertA[3] = new Point((stage.stageWidth / 4), (stage.stageHeight / 4) * 3);
			vertA[1] = new Point((stage.stageWidth / 4) * 3, (stage.stageHeight / 4));
			vertA[4] = new Point((stage.stageWidth / 4) * 3, (stage.stageHeight / 4) * 3);

			vertB[2] = new Point((stage.stageWidth / 8) * 3, (stage.stageHeight / 8) * 3);
			vertB[3] = new Point((stage.stageWidth / 8) * 3, (stage.stageHeight / 8) * 5);
			vertB[1] = new Point((stage.stageWidth / 8) * 5, (stage.stageHeight / 8) * 3);
			vertB[4] = new Point((stage.stageWidth / 8) * 5, (stage.stageHeight / 8) * 5);
		
			vertC[2] = new Point((stage.stageWidth / 16) * 7, (stage.stageHeight / 16) * 7);
			vertC[3] = new Point((stage.stageWidth / 16) * 7, (stage.stageHeight / 16) * 9);
			vertC[1] = new Point((stage.stageWidth / 16) * 9, (stage.stageHeight / 16) * 7);			
			vertC[4] = new Point((stage.stageWidth / 16) * 9, (stage.stageHeight / 16) * 9);

			drawReferencePts();
			drawIndefWalls();
		}
		
		private function drawReferencePts():void {
			
			for (var i:int = 1; i < 4; i++) {
				var mcRef:String = "references_" + alphaEnum[i];
				var vertRef:String = "vert" + alphaEnum[i];

				this[mcRef].graphics.clear();
				this[mcRef].graphics.lineStyle(2, 0xFFFF00);

				this[mcRef].graphics.clear();
				this[mcRef].graphics.lineStyle(1);	
				this[mcRef].graphics.drawCircle(this[vertRef][2].x, this[vertRef][2].y, 3);
				this[mcRef].graphics.drawCircle(this[vertRef][3].x, this[vertRef][3].y, 3);			
				this[mcRef].graphics.drawCircle(this[vertRef][1].x, this[vertRef][1].y, 3);			
				this[mcRef].graphics.drawCircle(this[vertRef][4].x, this[vertRef][4].y, 3);
				
				for each(var pnt2:* in source) {
					this["references_" + alphaEnum[i]].graphics.drawCircle( pnt2.x, pnt2.y, 5);
					//trace(pnt2);
				}
				for each(var pnt:* in bound) {
					this["references_" + alphaEnum[i]].graphics.drawCircle( pnt.x, pnt.y, 5);
				}
			}

		}
		
		private function click(evt:MouseEvent):void {
			trace("Mouse Info- x:" + evt.localX + " y: " + evt.localY + " obj: " + evt.currentTarget);
		}
		
		private function key(evt:KeyboardEvent):void {
			//trace("hello");
			var dir:Boolean = true;
			trace("Was @ rPos: " + player["Rposition"]);
			trace("Was @ worldPos: " + player["position"]);
			
			if(evt.keyCode == 38){
			dir = true;			
				if (prevDir != dir) {					
					trace("positionEnum[[Math.abs(player['position'] % 20)]: " + positionEnum[Math.abs(player["position"] % 20)]);
					//player["Rposition"] = positionEnum[Math.abs(player["position"] % 20)];		
					//player["position"] += 1;
					//player["Rposition"] += 1;
					trace(">>>>FORE Change Dir, pos: " + player["Rposition"]);
					advancePlr(dir);
				}else {
					//trace("Was @F rPos: " + player["Rposition"])
					player["position"] += 1;
					player["Rposition"] += 1;
					advancePlr(dir);
				}
			} else{			
				if(evt.keyCode == 40){
				dir = false;
					if (prevDir != dir) {
					trace("positionEnum[[Math.abs(player['position'] % 10)]: " + positionEnum[Math.abs(player["position"] % 10)]);
						//player["Rposition"] = positionEnum[Math.abs(player["position"] % 11)];
						//player["position"] -= 1;
						//player["Rposition"] -= 1;
						trace(">>>>BACK Change Dir, pos: " + player["Rposition"]);
						advancePlr(dir);
					}else {
						//trace("Was @B rPos: " + player["Rposition"]);
						player["position"] -= 1;
						player["Rposition"] -= 1;						
						advancePlr(dir);
					}
				}
			}
			trace("Is @ rPos: " + player["Rposition"]);
			trace("Is @ worldPos: " + player["position"]);

			prevDir = dir;
			//trace("player pos: " + player["position"]);
		}
		
		private function advancePlr(dir:Boolean = true,spd:int = 0):void {
			spd = player["speed"];
			
			if (dir) {
				calcNewScreen(spd,dir);
				updateScreen(dir);	
				trace("positionEnum[21]]: " + positionEnum[21]); 
				trace("player['Rposition']:" + player["Rposition"]);
				if (player["Rposition"] >=  positionEnum[21]){
					player["Rposition"] =  positionEnum[1];
					trace(">>>>>>>>>>New Forw Seg+++++++++++++++++++++");
					newSeg();
				}
			}else {
				trace("positionEnum[0]]: " + positionEnum[0]); 
				trace("player['Rposition']:" + player["Rposition"]);
				if (player["Rposition"] <= (positionEnum[0])){
					player["Rposition"] = (positionEnum[20]);
					trace(">>>>>>>New Back Seg+++++++++++++++++++++");
					newSeg(dir);
				}
				calcNewScreen(spd,dir);
				updateScreen(dir);	
			}			

			//prevDir = dir;
		
		}
		
		private function calcNewScreen(spd:int, dir:Boolean = true):void {
			if (slopeA == 0) {
				slopeA =  findSlope(source[2], bound[2]);			
				trace("slope: " + slopeA);
			}
			
			//slope = Math.ceil(slope);			
			//findNewBounds();
			
			wallLengthA = getDist(source[2], bound[2]);			
			if (intervalA == 0) {
				intervalA =  1;//findInterval(source[2], bound[2],wallLengthA);
				trace("interval: " + intervalA);
			}			
			if (slopeB == 0) {
				slopeB =  findSlope(source[2], bound[2]);			
				trace("slope: " + slopeB);
			}
			
			//slope = Math.ceil(slope);			
			//findNewBounds();
			
			wallLengthB = getDist(vertB[2], vertA[2]);			
			if (intervalB == 0) {
				intervalB =  1;//findInterval(vertB[2], vertA[2],wallLengthB);
				trace("interval: " + intervalB);
			}		
			if (slopeC == 0) {
				slopeC =  findSlope(source[2], bound[2]);			
				trace("slope: " + slopeC);
			}
			
			//slope = Math.ceil(slope);
			//findNewBounds();
			wallLengthC = getDist(vertC[2], vertB[2]);
			
			if (intervalC == 0) {
				intervalC =  1;//findInterval(vertB[2], vertA[2],wallLengthB);
				trace("interval: " + intervalB);
			}			
			//interval = Math.floor(interval);
			
			applyToQuadPts(vertA, intervalA*8, slopeA*8,dir);
			applyToQuadPts(vertB, intervalB*4, slopeB*4,dir);
			applyToQuadPts(vertC, intervalC*2, slopeC*2,dir);
		}
		
		private function applyToQuadPts(pntSet:Array, attrib1:*, attrib2:*, dir:Boolean = true):void {
			var mod:int = 0;			
			if (dir)
				mod = 1;
			else
				mod = -1;
			
			pntSet[2].x -= attrib1*mod;
			pntSet[2].y -= attrib2*mod;
			pntSet[3].x -= attrib1*mod;
			pntSet[3].y += attrib2*mod;
			pntSet[1].x += attrib1*mod;
			pntSet[1].y -= attrib2*mod;
			pntSet[4].x += attrib1*mod;
			pntSet[4].y += attrib2*mod;
		}
		
		private function findNewBounds():void {
			boundEst[2] = 0;
		}
		
		public function findEndPoint(pnt:Point,slope:int):Point {
			return (new Point(0,0));
		}
		
		private function updateScreen(dir:Boolean = true):void {
			//drawWalls();
			drawReferencePts();
			drawSegLines();
			drawObjs(dir);
		}
		
		private function drawObjs(dir:Boolean = true):void {
			var mod:int = 0;			
			if (dir)
				mod = 1;
			else
				mod = -1;
				
			for (var i:int = 0; i < 3; i++) {				
					//trace("obj" + i + " position: " + obj[i]["position"]);					
					
					var dist:int = (obj[i]["position"] - player["position"]);
					//trace("Dist: " + dist);
					//trace("Dist: " + dist);
					
					if (canSee(dist)) {						
						//if (!obj[i].visible)
						obj[i].visible = true;
						
						//trace("obj" + i + " dist: " + dist);
						
						obj[i].scaleX += ((dist/85)*5)*mod;
						obj[i].scaleY += ((dist /85) * 5)*mod;
					}else{
						obj[i].visible = false;
					}
			}
		}
		
		private function newSeg(dir:Boolean = true):void {
			//vertA[2] = vertB[2] as Point;
			//vertA[2] = vertB[3] as Point;
			//vertA[2] = vertB[1] as Point;
			//vertA[2] = vertB[4] as Point;
			//vertB[2] = vertC[2] as Point;
			//vertB[2] = vertC[3] as Point;
			//vertB[2] = vertC[1] as Point;
			//vertB[2] = vertC[4] as Point;
			
			if(dir){
				vertA[2] = new Point((stage.stageWidth / 4), (stage.stageHeight / 4));
				vertA[3] = new Point((stage.stageWidth / 4), (stage.stageHeight / 4) * 3);
				vertA[1] = new Point((stage.stageWidth / 4) * 3, (stage.stageHeight / 4));
				vertA[4] = new Point((stage.stageWidth / 4) * 3, (stage.stageHeight / 4) * 3);

				vertB[2] = new Point((stage.stageWidth / 8) * 3, (stage.stageHeight / 8) * 3);
				vertB[3] = new Point((stage.stageWidth / 8) * 3, (stage.stageHeight / 8) * 5);
				vertB[1] = new Point((stage.stageWidth / 8) * 5, (stage.stageHeight / 8) * 3);
				vertB[4] = new Point((stage.stageWidth / 8) * 5, (stage.stageHeight / 8) * 5);

				vertC[2] = new Point((stage.stageWidth / 16) * 7, (stage.stageHeight / 16) * 7);
				vertC[3] = new Point((stage.stageWidth / 16) * 7, (stage.stageHeight / 16) * 9);
				vertC[1] = new Point((stage.stageWidth / 16) * 9, (stage.stageHeight / 16) * 7);			
				vertC[4] = new Point((stage.stageWidth / 16) * 9, (stage.stageHeight / 16) * 9);
			} else {
				vertB[2] = new Point((stage.stageWidth / 4), (stage.stageHeight / 4));
				vertB[3] = new Point((stage.stageWidth / 4), (stage.stageHeight / 4) * 3);
				vertB[1] = new Point((stage.stageWidth / 4) * 3, (stage.stageHeight / 4));
				vertB[4] = new Point((stage.stageWidth / 4) * 3, (stage.stageHeight / 4) * 3);

				vertC[2] = new Point((stage.stageWidth / 8) * 3, (stage.stageHeight / 8) * 3);
				vertC[3] = new Point((stage.stageWidth / 8) * 3, (stage.stageHeight / 8) * 5);
				vertC[1] = new Point((stage.stageWidth / 8) * 5, (stage.stageHeight / 8) * 3);
				vertC[4] = new Point((stage.stageWidth / 8) * 5, (stage.stageHeight / 8) * 5);

				vertA[2] = new Point(0,0);
				vertA[3] = new Point(0, stage.stageHeight);
				vertA[1] = new Point(stage.stageWidth, 0);
				vertA[4] = new Point(stage.stageWidth, stage.stageHeight);
			}
		}
		
		private function drawSegLines():void {
			for (var i:int = 1; i < 4; i++) {
				var mcRef:String = "references_" + alphaEnum[i];
				var vertRef:String = "vert" + alphaEnum[i];

				this[mcRef].graphics.clear();
				this[mcRef].graphics.lineStyle(2, colors[2]);

				var a:Point = new Point(this[vertRef][2].x, this[vertRef][2].y)
				var width:Number = Point.distance(this[vertRef][2], this[vertRef][1]);
				var height:Number =  Point.distance(this[vertRef][1], this[vertRef][4]);
				this[mcRef].graphics.drawRect(a.x, a.y,  width, height);
				
			}				
		}
		
		private function drawIndefWalls():void {
				screenMC.graphics.clear();
				screenMC.graphics.lineStyle(2, colors[0]);
				screenMC.graphics.moveTo(bound[2].x, bound[2].y);
				screenMC.graphics.lineTo(vertC[2].x, vertC[2].y);
				screenMC.graphics.moveTo(bound[3].x, bound[3].y);
				screenMC.graphics.lineTo(vertC[3].x, vertC[3].y);
				
				screenMC.graphics.moveTo(bound[1].x, bound[1].y);
				screenMC.graphics.lineTo(vertC[1].x, vertC[1].y);
				screenMC.graphics.moveTo(bound[4].x, bound[4].y);
				screenMC.graphics.lineTo(vertC[4].x, vertC[4].y);
				
				var width:Number = Point.distance(vertC[2], vertC[1]);
				var height:Number =  Point.distance(vertC[1], vertC[4]);
				
				screenMC.graphics.lineStyle(2, 0x80FF00,.5);
				screenMC.graphics.drawRect(vertC[2].x, vertC[2].y, width, height);
		}
		
		private function drawWalls():void {			
			for (var i:int = 1; i < 4; i++){	
				var wallRef:String = "walls_" + alphaEnum[i];
				var vertRef:String = "vert" + alphaEnum[i];
				
				var vert2Ref:String;
				
				if (i == 1)
				vert2Ref = "bound";
				else if(i == 2)
				vert2Ref = "vertA";
				else if (i == 3) {
					vert2Ref = "vertB";
					//vertRef = "vertC";
				}
				
				this[wallRef].graphics.clear();
				this[wallRef].graphics.lineStyle(2, 0x80FF00);
				
				this[wallRef].graphics.moveTo(this[vert2Ref][2].x, this[vert2Ref][2].y);
				this[wallRef].graphics.lineTo(this[vertRef][2].x, this[vertRef][2].y);
				this[wallRef].graphics.moveTo(this[vert2Ref][3].x, this[vert2Ref][3].y);
				this[wallRef].graphics.lineTo(this[vertRef][3].x, this[vertRef][3].y);
				this[wallRef].graphics.moveTo(this[vert2Ref][1].x, this[vert2Ref][1].y);
				this[wallRef].graphics.lineTo(this[vertRef][1].x, this[vertRef][1].y);
				this[wallRef].graphics.moveTo(this[vert2Ref][4].x, this[vert2Ref][4].y);
				this[wallRef].graphics.lineTo(this[vertRef][4].x, this[vertRef][4].y);
			}
		}
		
		public function findSlope(a:Point, b:Point):Number {
			var slope:Number = 0.0;
			slope = (a.x - b.x) / (a.y - b.y);
			return(slope);
		}
		
		public function findInterval(a:Point, b:Point,len:Number):Number {			
			var dist:Number = len;
			trace("dist" + dist);
			
			return(dist/100);
		}
		
		public function getDist(a:Point, b:Point):Number {
			var len:Number = Point.distance(a, b);
			return len;
		}
				
		private function canSee(dist:int):Boolean {	
			if (dist <= player["sightLen"] && dist > 3){
				return true;
			}
			else{
				return false;
			}
			return false;
		}
		
		//
		//
		//OLD
		//
		//
		//
		
		private function drawScreen():void {
/*			//trace("stage.height: " + stage.height);
			//trace("stage.width: " + stage.width);
			
			var modX:int = 0;
			var modY:int = 0;

			//cX = (stage.stageWidth / 3) - modX;
			//cY =  modY - (stage.stageHeight / 3);
			
			screenMC.graphics.lineStyle(3);
			screenMC.graphics.drawRect((stage.stageWidth / 3)-modX , (stage.stageHeight / 3)-modY, stage.stageWidth / 3 , stage.stageHeight / 3);
			screenMC.graphics.lineStyle(10);
			//screenMC.graphics.drawRect(0,0, stage.stageWidth, stage.stageHeight);
			
			screenMC.graphics.lineStyle(3);
			//Q3
			screenMC.graphics.moveTo(0-modX, (stage.stageHeight)-modY);
			screenMC.graphics.lineTo((stage.stageWidth / 3) - modX , modY - (stage.stageHeight / 3));			
			//Q4
			screenMC.graphics.moveTo(stage.stageWidth-modX, modY-0);
			screenMC.graphics.lineTo(((stage.stageWidth / 3)*2)-modX , modY-(stage.stageHeight / 3));			
			//Q1
			screenMC.graphics.moveTo(stage.stageWidth-modX, modY-stage.stageHeight);
			screenMC.graphics.lineTo(((stage.stageWidth / 3)*2)-modX , modY-((stage.stageHeight / 3)*2));
			//Q2
			screenMC.graphics.moveTo(0-modX, modY-stage.stageHeight);
			screenMC.graphics.lineTo((stage.stageWidth / 3)-modX , modY-((stage.stageHeight / 3)*2));
*/		}
		private function move(dir:int):void {
			/*
			for (var i:int = 0; i < 3; i++) {				
					//trace("obj" + i + " position: " + obj[i]["position"]);					
					
					var dist:int = (obj[i]["position"] - player["position"]);
					//trace("Dist: " + dist);
					
					if (canSee(dist)) {						
						//if (!obj[i].visible)
						obj[i].visible = true;
						
						//trace("obj" + i + " dist: " + dist);
						
						obj[i].scaleX += ((dist/85)*5)*dir;
						obj[i].scaleY += ((dist /85) * 5) * dir;
						//trace("obj" + i + " x: " + obj[i].name + "," + obj[i].scaleX);
						//trace("obj" + i + " y: " + obj[i].name + "," + obj[i].scaleY);
					}else{
						obj[i].visible = false;
					}
			}
						//screenMC.scaleX += ((dist/400)*5)*dir;
						//screenMC.scaleY += ((dist/400)*5)*dir;

			screenMC.graphics.clear();
			screenMC.graphics.lineStyle(1);
			screenMC.graphics.drawCircle(cX, cY, 5);
			screenMC.graphics.lineStyle(1);
			screenMC.graphics.drawCircle( -cX, -cY, 5);
			screenMC.graphics.moveTo(cX, cY);
			screenMC.graphics.lineTo((stage.stageWidth / 3) - 400 , 300 - (stage.stageHeight / 3));			

			cX -= 5;
			cY += 5; 
			*/
		}


		
	}
	
}